﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Collections;
namespace Rekenmachine
{
    ///    <summary>
    ///     Dit is de BreukContainer
    ///     Omvat methodes om lijsten van breuken te beheren.
    ///    </summary>
    class BreukContainer:CollectionBase
    {
        protected List<Breuk> breuken = new List<Breuk>();


        public virtual void Add(Breuk b)
        {
            Debug.WriteLine("AddBreuk called");
            breuken.Add(b);
        }
        public virtual void Add(params Breuk[] breuken)
        {
            foreach (Breuk b in breuken)
            {
                Add(b);
            }

        }
        public void Remove(Breuk b)
        {
            breuken.Remove(b);
        }
        /// <summary>
        /// Een bepaald aantal breuken bij elkaar optellen
        /// </summary>
        /// <param name="breuken"></param>
        /// <returns>Een nieuwe breuk waar al de andere breuken zijn bij elkaar geteld</returns>
        public Breuk aantalBreukenOptellen(params Breuk[] breuken)
        {
            Debug.WriteLine("aantalBreukenOptellen called");
            Breuk temp = null;
            if (breuken.Length > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Length; i++)
                {
                    temp = temp + breuken[i];
                }
            }
            return temp;
        }

        public Breuk LijstOptellen()
        {
            Debug.WriteLine("LijstOptellen called");
            Breuk temp = null;
            if (breuken.Count > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Count; i++)
                {
                    temp = temp + breuken[i];
                }
            }
            return temp;
        }

        /// <summary>
        /// Een bepaald aantal breuken van elkaar aftrekken
        /// </summary>
        /// <param name="breuken"></param>
        /// <returns>Een nieuwe breuk waar al de andere breuken zijn afgetrokken</returns>
        public Breuk aantalBreukenAftrekken(params Breuk[] breuken)
        {
            Debug.WriteLine("aantalBreukenAftrekken called");
            Breuk temp = null;
            if (breuken.Length > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Length; i++)
                {
                    temp = temp - breuken[i];
                }
            }
            return temp;
        }


        public Breuk LijstAftrekken()
        {
            Debug.WriteLine("LijstAftrekken called");
            Breuk temp = null;
            if (breuken.Count > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Count; i++)
                {
                    temp = temp - breuken[i];
                }
            }
            return temp;
        }

        /// <summary>
        /// Quotïent van alle breuken
        /// </summary>
        /// <param name="breuken"></param>
        /// <returns>Een nieuwe breuk. Het quotïent van alle breuken</returns>
        public Breuk aantalBreukenDelen(params Breuk[] breuken)
        {
            Debug.WriteLine("aantalBreukenDelen called");
            Breuk temp = null;
            if (breuken.Length > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Length; i++)
                {
                    temp = temp / breuken[i];
                }
            }
            return temp;
        }

        public Breuk LijstDelen()
        {
            Debug.WriteLine("LijstDelen called");
            Breuk temp = null;
            if (breuken.Count > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Count; i++)
                {
                    temp = temp / breuken[i];
                }
            }
            return temp;
        }

        /// <summary>
        /// Product van alle breuken
        /// </summary>
        /// <param name="breuken"></param>
        /// <returns>Een nieuwe breuk. Het product van alle breuken</returns>
        public Breuk aantalBreukenVermenigvuldigen(params Breuk[] breuken)
        {
            Debug.WriteLine("aantalBreukenVermenigvuldigen called");
            Breuk temp = null;
            if (breuken.Length > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Length; i++)
                {
                    temp = temp * breuken[i];
                }
            }
            return temp;
        }

        public Breuk LijstVermenigvuldigen()
        {
            Debug.WriteLine("LijstVermenigvuldigen called");
            Breuk temp = null;
            if (breuken.Count > 0)
            {
                temp = new Breuk(breuken[0].Teller, breuken[0].Noemer);
                for (int i = 1; i < breuken.Count; i++)
                {
                    temp = temp * breuken[i];
                }
            }
            return temp;
        }

        public override String ToString()
        {
            Debug.WriteLine("ToString van klasse BreukContainer called");
            StringBuilder uitvoer = new StringBuilder("\nLijst van de huidige breuken:\n");

            if (breuken.Count > 0)
            {
                breuken.ForEach(delegate(Breuk b) { uitvoer.Append(b.ToString() + " + "); });

                uitvoer.Remove(uitvoer.Length - 2, 2);
                Breuk temp = LijstOptellen();
                uitvoer.Append("= " + temp.ToString() + " ");
                temp.Vereenvoudig();
                uitvoer.Append("= " + temp.ToString() + " = " + temp.Decimaal(3) + "\n");

                breuken.ForEach(delegate(Breuk b) { uitvoer.Append(b.ToString() + " - "); });

                uitvoer.Remove(uitvoer.Length - 2, 2);
                temp = LijstAftrekken();
                uitvoer.Append("= " + temp.ToString() + " ");
                temp.Vereenvoudig();
                uitvoer.Append("= " + temp.ToString() + " = " + temp.Decimaal(3) + "\n");

                breuken.ForEach(delegate(Breuk b) { uitvoer.Append(b.ToString() + " * "); });

                uitvoer.Remove(uitvoer.Length - 2, 2);
                temp = LijstVermenigvuldigen();
                uitvoer.Append("= " + temp.ToString() + " ");
                temp.Vereenvoudig();
                uitvoer.Append("= " + temp.ToString() + " = " + temp.Decimaal(3) + "\n");


                breuken.ForEach(delegate(Breuk b) { uitvoer.Append(b.ToString() + " : "); });

                uitvoer.Remove(uitvoer.Length - 2, 2);
                temp = LijstDelen();
                uitvoer.Append("= " + temp.ToString() + " ");
                temp.Vereenvoudig();
                uitvoer.Append("= " + temp.ToString() + " = " + temp.Decimaal(3) + "\n");

                //sorteren
                uitvoer.Append("\n\nVan klein naar groot: ");
                breuken.Sort(delegate(Breuk b1, Breuk b2) { return b1.CompareTo(b2); });
                breuken.ForEach(delegate(Breuk b) { uitvoer.Append(String.Format("{0}/{1} ", b.Teller, b.Noemer)); });

                uitvoer.Append("\nVan groot naar klein: ");
                breuken.Sort(delegate(Breuk b1, Breuk b2) { return b2.CompareTo(b1); });
                breuken.ForEach(delegate(Breuk b) { uitvoer.Append(String.Format("{0}/{1} ", b.Teller, b.Noemer)); });
            }

            return uitvoer.ToString();
        }


        internal List<Breuk> Breuken
        {
            get { return breuken; }
            set { breuken = value; }
        }
        public Breuk this[int index]
        {
            get
            {
                return (Breuk)breuken[index];
            }
            set
            {
                breuken[index] = value;
            }
        }

    }
}
